package main

import (
	nlanguage "cloud.google.com/go/language/apiv1"
	texttospeech "cloud.google.com/go/texttospeech/apiv1"
	"cloud.google.com/go/translate"
	"context"
	"flag"
	"fmt"
	"golang.org/x/text/language"
	"google.golang.org/api/option"
	nlanguagepb "google.golang.org/genproto/googleapis/cloud/language/v1"
	texttospeechpb "google.golang.org/genproto/googleapis/cloud/texttospeech/v1"
	"google.golang.org/grpc"
	"log"
	"net"
	"os"
	"path/filepath"
	"qweewq.tk/ConsultingPlatform/cmd/consultative"
)

var authJsonFile = flag.String("f", "app.json", "APP认证服务的json")
var mp3StorePath = flag.String("mp3", `.`, "存储mp3的路径")
var listenAddress = flag.String("listen", "0.0.0.0:8080", "监听ip:port地址")
var domainName = flag.String("domain", "127.0.0.1", "域名")

type ServiceImpl struct {

}

func toString(lang consultative.MsgLang) string {
	switch lang {
	case consultative.MsgLang_zh:
		return "zh"
	case consultative.MsgLang_en:
		return "en"
	default:
		return "en"
	}
}

func (s *ServiceImpl) Translate(ctx context.Context, req *consultative.TransRequest) (*consultative.TransResponse, error) {
	client, err := translate.NewClient(ctx, option.WithCredentialsFile(*authJsonFile))

	if err != nil {
		panic(err)
	}
	defer client.Close()

	targetText, err := language.Parse(toString(req.Target))
	if err != nil {
		log.Println("Failed to parse target language: %v", err)
		return nil, err
	}

	translations, err := client.Translate(ctx, req.TransMsg, targetText, nil)
	if err != nil {
		log.Println("Failed to google text: %v", err)
		return nil, err
	}

	res := new(consultative.TransResponse)
	for i, v := range translations {
		res.Texts = append(res.Texts, v.Text)
		fmt.Printf("Text: %v\n", req.TransMsg[i])
		fmt.Printf("Translation: %v\n", v.Text)
	}
	return res, nil
}

func (s *ServiceImpl) Text2Audio(ctx context.Context, req *consultative.AudioRequest) (*consultative.AudioResponse, error) {
	client, err := texttospeech.NewClient(ctx, option.WithCredentialsFile(*authJsonFile))
	if err != nil {
		panic(err)
	}

	defer client.Close()

	filename := fmt.Sprintf("%s/%s.mp3", *mp3StorePath, req.Filename)
	fileInfo, _ := os.Stat(filename)
	if fileInfo == nil {
		f, err := os.OpenFile(filename, os.O_WRONLY|os.O_TRUNC, 0644)
		if os.IsNotExist(err) {
			f, err = os.Create(filename)

			if err != nil {
				return nil, err
			}
		} else {
			//已经存在则直接返回相应的地址即可
			goto exit_
		}
		req := texttospeechpb.SynthesizeSpeechRequest{
			// Set the text input to be synthesized.
			Input: &texttospeechpb.SynthesisInput{
				InputSource: &texttospeechpb.SynthesisInput_Text{Text: req.Text},
			},
			// Build the voice request, select the language code ("en-US") and the SSML
			// voice gender ("neutral").
			Voice: &texttospeechpb.VoiceSelectionParams{
				LanguageCode: toString(req.Source),
				SsmlGender:   texttospeechpb.SsmlVoiceGender_NEUTRAL,
			},
			// Select the type of audio file you want returned.
			AudioConfig: &texttospeechpb.AudioConfig{
				AudioEncoding: texttospeechpb.AudioEncoding_MP3,
			},
		}

		resp, err := client.SynthesizeSpeech(ctx, &req)
		if err != nil {
			log.Println(err)
			return nil, err
		}

		nOffset := 0
		for nOffset != len(resp.AudioContent) {
			n, err := f.Write(resp.AudioContent[nOffset:])
			nOffset += n
			if err != nil {
				f.Close()
				os.Remove(filename)
				f = nil
				break
			}
		}

		if f != nil {
			f.Close()
		}

		if err != nil {
			log.Println(err)
			return nil, err
		}
		fmt.Printf("Audio content written to file: %s\n", filename)
	}

exit_:
	_, fName := filepath.Split(filename)
	res := new(consultative.AudioResponse)
	res.Url = fmt.Sprintf("%s/%s", *domainName, fName)
	return res, nil
}

func (s *ServiceImpl) Analyze(ctx context.Context, req *consultative.AnalyzeRequest) (*consultative.AnalyzResponse, error) {
	client, err := nlanguage.NewClient(ctx, option.WithCredentialsFile(*authJsonFile))
	if err != nil {
		panic(err)
	}

	defer client.Close()

	entities, err := client.AnalyzeEntities(ctx, &nlanguagepb.AnalyzeEntitiesRequest{
		Document: &nlanguagepb.Document{
			Type: nlanguagepb.Document_PLAIN_TEXT,
			Source: &nlanguagepb.Document_Content{
				Content: req.Text,
			},
		},
		EncodingType: nlanguagepb.EncodingType_UTF8,
	})

	if err != nil {
		log.Println("Failed to classify text: %v", err)
		return nil, err
	}

	var keywords []string

	for _, v := range entities.Entities {
		keywords = append(keywords, v.Name)
	}

	log.Println(keywords)

	res := new(consultative.AnalyzResponse)
	res.Keywords = append(res.Keywords, keywords...)
	return res, nil
}

func main() {
	flag.Parse()
	lis, err := net.Listen("tcp", *listenAddress)  //监听
	if err != nil {
		log.Fatalf("监听失败: %v", err)
	}
	s := grpc.NewServer() //创建gRPC服务
	var cb = new(ServiceImpl)
	consultative.RegisterIntegSerivecServer(s, cb)
	if err := s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
	//log.Fatalln(http.ListenAndServe(*listenAddress, nil))
}
